package com.xd.core.system.service.impl;


import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xd.common.exception.XkdException;
import com.xd.common.util.SecurityUtil;
import com.xd.core.system.dto.AddGroupDto;
import com.xd.core.system.entity.GroupInfo;
import com.xd.core.system.entity.UserGroup;
import com.xd.core.system.mapper.GroupInfoMapper;
import com.xd.core.system.mapper.UserGroupMapper;
import com.xd.core.system.service.IGroupInfoService;
import com.xd.core.system.service.ISysUserService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author ZX
 * @since 2024-07-25
 */
@Slf4j
@Service
public class GroupInfoServiceImpl extends ServiceImpl<GroupInfoMapper, GroupInfo> implements IGroupInfoService {
    @Autowired
    private GroupInfoMapper groupInfoMapper;
    @Autowired
    private ISysUserService iSysUserService;
    @Autowired
    private UserGroupMapper userGroupMapper;

    @Override
    public void addGroup(AddGroupDto addGroupDto) {
        Integer companyId = SecurityUtil.getLoginCompanyId();
        GroupInfo groupInfo = new GroupInfo();
        groupInfo.setGroupName(addGroupDto.getGroupName())
                .setCompanyId(companyId)
                .setPid(addGroupDto.getPid())
                .setRemark(addGroupDto.getRemark());
        groupInfoMapper.insert(groupInfo);
    }

    @Override
    public List<GroupInfo> findGroups(String groupName) {
        Integer companyId = SecurityUtil.getLoginCompanyId();
        if (companyId == 0){
            return null;
        }
        List<Integer> groupIds = iSysUserService.getGroupIds();
        List<GroupInfo> groupInfos = groupInfoMapper.findGroupsByGroupIds(groupIds, groupName);
        List<GroupInfo> groupTree = getGroupTree(groupInfos);
        return groupTree;
    }

    /*
     * groupInfos:通过公司ID查出的所有部门
     * groupIds：空集合 用来装查出来的部门ID集合
     * id：查询所属的部门以及下属部门
     * */
    @Override
    public void getChildIds(Integer id, List<Integer> groupIds, List<GroupInfo> groupInfos) {
        for (GroupInfo groupInfo : groupInfos) {
            if (groupInfo.getPid().equals(id)) {
                groupIds.add(groupInfo.getId());
                getChildIds(groupInfo.getId(), groupIds, groupInfos);
            }
        }
    }

    @Override
    public void delGroup(Integer id) {
        GroupInfo a = groupInfoMapper.selectById(id);

        if (a.getPid().equals(0)){
            throw new XkdException("不允许删除总部");
        }
        /*
         * 不允许删除带子集的部门
         * */
        Integer i = groupInfoMapper.selectCount(new LambdaQueryWrapper<GroupInfo>().eq(GroupInfo::getPid, id));
        if (i > 0) {
            throw new XkdException("先删除子部门");
        }
        /*
         * 不允许删除有人的部门
         * */
        Integer j = userGroupMapper.selectCount(new LambdaQueryWrapper<UserGroup>().eq(UserGroup::getGroupId, id));
        if (j > 0) {
            throw new XkdException("先移除部门下员工");
        }
        groupInfoMapper.deleteById(id);
    }

    @Override
    public List<GroupInfo> updateGroupsTree(Integer userId) {
        Integer loginCompanyId = SecurityUtil.getLoginCompanyId();
        List<GroupInfo> groupInfos = groupInfoMapper.selectList(new LambdaQueryWrapper<GroupInfo>().eq(GroupInfo::getCompanyId, loginCompanyId));
        if (userId == null)//如果userId为空 第一次新建员工
            return getGroupTree(groupInfos);
        String dataGroup = iSysUserService.getById(userId).getDataGroup();
        if (StringUtils.isEmpty(dataGroup))
            return getGroupTree(groupInfos);

        List<Integer> collect = Arrays.stream(dataGroup.split(",")).map(Integer::valueOf).collect(Collectors.toList());
        groupInfos.forEach(g -> {
            collect.forEach(c -> {
                if (g.getId().equals(c))
                    g.setGroupInfoStatus(true);
            });
        });
        return getGroupTree(groupInfos);
    }

    @Override
    public List<GroupInfo> groupDropDown() {
        Integer companyId = SecurityUtil.getLoginCompanyId();
        List<Integer> groupIds = iSysUserService.getGroupIds();
        List<GroupInfo> groupInfos = groupInfoMapper.groupDropDown(groupIds,companyId);
        return getGroupTree(groupInfos);
    }

    @Override
    public List<GroupInfo> dataPerDropDown() {
        Integer companyId = SecurityUtil.getLoginCompanyId();
        List<GroupInfo> groupInfos = groupInfoMapper.groupDropDown(null, companyId);
        return getGroupTree(groupInfos);
    }

    public List<GroupInfo> getGroupTree(List<GroupInfo> groupInfos) {
        List<GroupInfo> groupTree = new ArrayList<>();
        HashMap<Integer, GroupInfo> map = new HashMap<>();
        groupInfos.forEach(
                g -> {
                    map.put(g.getId(), g);
                    GroupInfo parent = map.get(g.getPid());
                    if (parent != null) {
                        parent.addChild(g);
                    } else {
                        groupTree.add(g);
                    }
                }
        );
        return groupTree;
    }

    private int getCount(List<GroupInfo> groupTree) {
        int total = 0;
        for (GroupInfo groupInfo : groupTree) {
            List<GroupInfo> children = groupInfo.getChildren();
            if (CollectionUtils.isNotEmpty(children)) {
                int count = getCount(children);
                groupInfo.addUserCounts(count);
            }
            total = total + groupInfo.getUserCounts();
        }
        return total;
    }
}
